# Logtrack-ng - Module for drawing tables similar to DB tables
# Copyright (C) 2007 Jan "Xatrix" Kucera
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
# USA.

=head1 NAME

Logtrack::Table - module for drawing tables similar to DB tables

=head1 DESCRIPTION

Module display every SQL query result like output in DB programs
Module first determines maximum size of each row and then it draw
lines, table description and content of query. 

=head2 FUNCTIONS

=over 4

=cut

package Logtrack::Table;

use Exporter;
use Switch;

@ISA = qw(Exporter);
@EXPORT = qw();

use strict;

our @EXPORT_OK;

=item
Constructor - only inicialize output variable
=cut
sub new {
	my($self) = @_;
	my $class = ref $self || $self;
	my $table = {
		'output' => ''
	};

	bless ($table,$class);
	return ($table);
}

=item
Return latest generated output
=cut
sub get_output {
	my ($self) = @_;
	return $self->{output};
}

=item
Function returns structure which contains maximal sizes of every rows
=cut

sub get_sizes ($$) {
	my ($r_captions, $r_content) = @_;
	my (@max_lengths,$length,$num_rows,$index,$row);
	$num_rows = @{$r_captions};
	for ($row=0; $row < $num_rows; $row++) {
		$max_lengths[$row] = length($$r_captions[$row]);
	}
	
	for($index=0;$index < @{$r_content} ;$index++) {
		for ($row=0;$row < $num_rows;$row++) {
			$length = length($$r_content[$index][$row]);
			$max_lengths[$row] = $length if($length > $max_lengths[$row]);
		}
	}
	return \@max_lengths;
}

=item
Function which calls all table drawing functions and returns output variable
which contains all data
=cut
sub draw_table ($$$) {
	my ($self,$r_captions,$r_content) = @_;
	my $r_lengths = get_sizes($r_captions,$r_content);
	$self->{output} = '';
	
	$self->draw_line($r_lengths);
	$self->draw_label($r_captions,$r_lengths);	
	$self->draw_line($r_lengths);
	$self->draw_content($r_content,$r_lengths);	
	$self->draw_line($r_lengths,$r_lengths);
	return $self->{output};
}
=item
Function draws all data - it executes drawing function for displaying cells
=cut
sub draw_content {
	my ($self,$r_content,$r_lengths) = @_;
	for(my $index=0; $index < @{$r_content}; $index++) {
		for (my $row=0;$row < @{$r_lengths};$row++) {
			$self->draw_cell($$r_content[$index][$row],$$r_lengths[$row]);
		}
		$self->{output} .= "|\n";	
	}
}

sub draw_line {
	my ($self,$r_lengths) = @_;
	foreach my $length (@{$r_lengths}) {
		$self->{output} .= '+'. '-' x ($length+2);
	}
	$self->{output} .= '+' ."\n";
}

sub draw_label {
	my ($self,$r_captions,$r_lengths) = @_;
	for(my $index=0; $index < @{$r_captions}; $index++) {
		$self->draw_cell($$r_captions[$index],$$r_lengths[$index]);
	}
	$self->{output} .= '|' ."\n";
}

sub draw_cell {
	my ($self,$content,$size) = @_;
	my ($length,$space,$l_space,$r_space);
	use integer;
	$length = length($content);
	
	if($size < $length) {
		die 'Content '. $content .' is too big for cell'."\n";	
	}
	
	$space = $size - $length;
	
	if($space % 2) {
		$l_space = $space/2 + 1;
		$r_space = ($l_space + 1);
	}
	else {
		$l_space = $r_space = ($space/2) + 1;
	}
	$self->{output} .= '|'. ' ' x $l_space;
	$self->{output} .= $content;
	$self->{output} .= ' ' x $r_space;
	no integer;	
}

1;

__END__